﻿using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Net.Http;
using System.Text;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
using Helpers;
using Polly.Extensions.Http;
using Polly;
using Polly.Contrib.WaitAndRetry;
using Polly.CircuitBreaker;

namespace Microsoft.Extensions.DependencyInjection
{
    public static class ApiCacheHelperExtensions
    {
        public static IServiceCollection AddApiCacheHelperz(this IServiceCollection services, IConfiguration configuration, Action<ApiCacheOptions> configure = null)
        {
            services.AddOptions<ApiCacheOptions>()
             .Bind(configuration.GetSection(ApiCacheOptions.SectionName))
             .ValidateDataAnnotations();
            services.PostConfigure<ApiCacheOptions>(x =>
            {
                configure?.Invoke(x);
            });
            services.AddSingleton<ApiCacheOptions>(x => x.GetRequiredService<IOptions<ApiCacheOptions>>().Value);

            services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();

            //WeedFsHttpClient 熔断加重试
            var cbPolicy = Policy<HttpResponseMessage>.Handle<Exception>()
                .CircuitBreakerAsync(10, TimeSpan.FromSeconds(60));
            var retryPolicy = HttpPolicyExtensions
                .HandleTransientHttpError()
                .WaitAndRetryAsync(Backoff.DecorrelatedJitterBackoffV2(medianFirstRetryDelay: TimeSpan.FromSeconds(1), retryCount: 3, fastFirst: true));
            services.AddHttpClient<WeedFsHttpClient>()
                .ConfigureHttpClient(x =>
                {
                    x.Timeout = TimeSpan.FromSeconds(5);
                })
                .ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler
                {
                    AutomaticDecompression = System.Net.DecompressionMethods.All
                })
                .AddPolicyHandler(cbPolicy)
                .AddPolicyHandler(retryPolicy);

            return services;
        }
    }
}
